﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using PROFIP.Persistence;
using PROFIP.Persistence.DTO;
using PROFIP.Utils;
using PROFIP.Persistence.DTO.Scales;

namespace PROFIP
{
    public partial class MainForm : Form
    {
        //Number of Avaliation sheets
        static int NUM_AVALS = 4;

        //PANSS
        PANSSForm[] panssArray = new PANSSForm[NUM_AVALS];
        PANSSDTO[] panssDTOArray = new PANSSDTO[NUM_AVALS];

        //BPRS
        BPRSForm[] bprsArray = new BPRSForm[NUM_AVALS];
        BPRSDTO[] bprsDTOArray = new BPRSDTO[NUM_AVALS];

        //MADRS
        MADRSForm[] madrsArray = new MADRSForm[NUM_AVALS];
        MADRSDTO[] madrsDTOArray = new MADRSDTO[NUM_AVALS];

        //PAS
        PASForm[] pasArray = new PASForm[NUM_AVALS];
        PASDTO[] pasDTOArray = new PASDTO[NUM_AVALS];

        //NOSDUP
        NOSDUPForm[] nosdupArray = new NOSDUPForm[NUM_AVALS];
        NOSDUPDTO[] nosdupDTOArray = new NOSDUPDTO[NUM_AVALS];

        //ASI
        ASIForm[] asiArray = new ASIForm[NUM_AVALS];
        ASIDTO[] asiDTOArray = new ASIDTO[NUM_AVALS];

        //WHOQOLBREF
        WHOQOLBREFForm[] whoqolbrefArray = new WHOQOLBREFForm[NUM_AVALS];
        WHOQOLBREFDTO[] whoqolbrefDTOArray = new WHOQOLBREFDTO[NUM_AVALS];

        //AGF
        AGFForm[] agfArray = new AGFForm[NUM_AVALS];
        AGFDTO[] agfDTOArray = new AGFDTO[NUM_AVALS];

        public MainForm()
        {
            InitializeComponent();
        }

        private void Form_Load(object sender, EventArgs e)
        {
//            treeView1.ExpandAll();
//            this.WindowState = FormWindowState.Maximized;
        }

        /***********
         * BUTTONS *
         ***********/
        public Button getPANSSButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return PANSSAval1_Button;
            }
            return null;
        }

        public Button getBPRSButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return BPRSAval1_Button;
            }
            return null;
        }

        public Button getMADRSButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return MADRSAval1_Button;
            }
            return null;
        }

        public Button getPASButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return PASAval1_Button;
            }
            return null;
        }

        public Button getNOSDUPButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return NOSDUPAval1_Button;
            }
            return null;
        }

        public Button getASIButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return ASIAval1_Button;
            }
            return null;
        }

        public Button getWHOQOLBREFButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return WHOQOLBREFAval1_Button;
            }
            return null;
        }

        public Button getAGFButton(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return AGFAval1_Button;
            }
            return null;
        }

        /***************
         * SCORE LABEL *
         ***************/
        public Label getPANSSScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return PANSSAval1_Score;
            }
            return null;
        }

        public Label getBPRSScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return BPRSAval1_Score;
            }
            return null;
        }

        public Label getMADRSScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return MADRSAval1_Score;
            }
            return null;
        }

        public Label getPASScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return PASAval1_Score;
            }
            return null;
        }

        public Label getNOSDUPScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return NOSDUPAval1_Score;
            }
            return null;
        }

        public Label getASIScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return ASIAval1_Score;
            }
            return null;
        }

        public Label getWHOQOLBREFScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return WHOQOLBREFAval1_Score;
            }
            return null;
        }

        public Label getAGFScoreLabel(int avaliationSheetIndex)
        {
            switch (avaliationSheetIndex)
            {
                case 0: return AGFAval1_Score;
            }
            return null;
        }




        /*****************
         * SCALE OPENING *
         *****************/
        //Generic method to handle click
        private void genericScale_Click<T,U>(object sender, EventArgs e, Func<int, Button> getBtnFunc, ref T[] scaleArray, ref U[] scaleDTOArray)
            where T:ScaleForm 
            where U:ScaleDTO
        {
            int avalIndex = -1;
            for (int i = 0; i < NUM_AVALS; i++)
            {
                if (sender.Equals(getBtnFunc(i)))
                {
                    avalIndex = i;
                    break;
                }
            }
            if (avalIndex == -1)
            {
                return;
            }
            T scale = scaleArray[avalIndex];

            if (scale != null)
            {
                if (!scale.IsDisposed)
                {
                    scale.Close();
                }
                scaleArray[avalIndex] = null;
            }

//            scale = scaleArray[avalIndex] = (T)Activator.CreateInstance(typeof(T), new object[] { this, scaleDTOArray[avalIndex], avalIndex });
            scale = initializeScaleForm<T, U>(scaleArray, scaleDTOArray[avalIndex], avalIndex);
            ((Button)sender).Enabled = false;
            scale.Show();
        }

        private T initializeScaleForm<T, U>(T[] scaleArray, U dto, int avaliationSheetIndex)
            where T : ScaleForm
            where U : ScaleDTO
        {
            return scaleArray[avaliationSheetIndex] = (T)Activator.CreateInstance(typeof(T), new object[] { this, dto, avaliationSheetIndex });
        }

        private void PANSS_Click(object sender, EventArgs e)
        {
            genericScale_Click<PANSSForm, PANSSDTO>(sender, e, getPANSSButton, ref panssArray, ref panssDTOArray);
        }

        private void BPRS_Click(object sender, EventArgs e)
        {
            genericScale_Click<BPRSForm, BPRSDTO>(sender, e, getBPRSButton, ref bprsArray, ref bprsDTOArray);
        }

        private void MADRS_Click(object sender, EventArgs e)
        {
            genericScale_Click<MADRSForm, MADRSDTO>(sender, e, getMADRSButton, ref madrsArray, ref madrsDTOArray);
        }

        private void PAS_Click(object sender, EventArgs e)
        {
            genericScale_Click<PASForm, PASDTO>(sender, e, getPASButton, ref pasArray, ref pasDTOArray);
        }

        private void NOSDUP_Click(object sender, EventArgs e)
        {
            genericScale_Click<NOSDUPForm, NOSDUPDTO>(sender, e, getNOSDUPButton, ref nosdupArray, ref nosdupDTOArray);
        }

        private void ASI_Click(object sender, EventArgs e)
        {
            genericScale_Click<ASIForm, ASIDTO>(sender, e, getASIButton, ref asiArray, ref asiDTOArray);
        }

        private void WHOQOLBREF_Click(object sender, EventArgs e)
        {
            genericScale_Click<WHOQOLBREFForm, WHOQOLBREFDTO>(sender, e, getWHOQOLBREFButton, ref whoqolbrefArray, ref whoqolbrefDTOArray);
        }

        private void AGF_Click(object sender, EventArgs e)
        {
            genericScale_Click<AGFForm, AGFDTO>(sender, e, getAGFButton, ref agfArray, ref agfDTOArray);
        }

        /***************
         * SCALE CLOSE *
         ***************/
        public void updatePANSS(PANSSDTO dto, int avaliationSheetIndex)
        {
            PANSSForm panss = panssArray[avaliationSheetIndex];

            panssDTOArray[avaliationSheetIndex] = dto;

            String positivo = panss.GetScorePositivo();
            String negativo = panss.GetScoreNegativo();
            String geral = panss.GetScoreGeral();
            String tipoSintomatologico = panss.GetTipoSintomatologico();


            if (positivo != "0" || negativo != "0" || geral != "0")
            {
                getPANSSScoreLabel(avaliationSheetIndex).Text = "Negativo = " + negativo +
                    " | Positivo = " + positivo +
                    " | Geral = " + geral +
                    " | Tipo Sintomatológico = " + tipoSintomatologico;
            }

            getPANSSButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateBPRS(BPRSDTO dto, int avaliationSheetIndex)
        {
            BPRSForm bprs = bprsArray[avaliationSheetIndex];
            bprsDTOArray[avaliationSheetIndex] = dto;

            if (bprs.GetScore().Trim().Length != 0)
            {
                getBPRSScoreLabel(avaliationSheetIndex).Text = bprs.GetScore();
            }
            getBPRSButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateMADRS(MADRSDTO dto, int avaliationSheetIndex)
        {
            MADRSForm madrs = madrsArray[avaliationSheetIndex];
            madrsDTOArray[avaliationSheetIndex] = dto;

            if (madrs.GetScore().Trim().Length != 0)
            {
                getMADRSScoreLabel(avaliationSheetIndex).Text = madrs.GetScore();
            }
            getMADRSButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updatePAS(PASDTO dto, int avaliationSheetIndex)
        {
            PASForm pas = pasArray[avaliationSheetIndex];
            pasDTOArray[avaliationSheetIndex] = dto;

            int infanciaScore = pas.getInfanciaScore();
            int inicioAdlescenciaScore = pas.getInicioAdolescenciaScore();
            int finalAdolescenciaScore = pas.getFinalAdolescenciaScore();
            int adulticiaScore = pas.getAdulticiaScore();
            int geralScore = pas.getGeralScore();

            if (infanciaScore > 0 || inicioAdlescenciaScore > 0 ||
                finalAdolescenciaScore > 0 || adulticiaScore > 0 ||
                geralScore > 0)
            {
                getPASScoreLabel(avaliationSheetIndex).Text = "Infancia = "+infanciaScore+
                    " | Inicio Adolescencia = "+inicioAdlescenciaScore+
                    " | Final Adolescencia = "+finalAdolescenciaScore+
                    " | Adulticia = "+adulticiaScore+
                    " | Geral = "+geralScore;
 
            }

            getPASButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateNOSDUP(NOSDUPDTO dto, int avaliationSheetIndex)
        {
            //TODO!!
            //this.label92.Text = nosdup.label1.Text;
            getNOSDUPButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateASI(ASIDTO dto, int avaliationSheetIndex)
        {
            //TODO!!
            ASIForm asi = asiArray[avaliationSheetIndex];
            //asiDTOArray[avaliationSheetIndex] = dto;
            getASIButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateWHOQOLBREF(WHOQOLBREFDTO dto, int avaliationSheetIndex)
        {
            //TODO!!
            WHOQOLBREFForm whoqolbref = whoqolbrefArray[avaliationSheetIndex];
            //whoqolbrefDTOArray[avaliationSheetIndex] = dto;
            getWHOQOLBREFButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        public void updateAGF(AGFDTO dto, int avaliationSheetIndex)
        {
            AGFForm agf = agfArray[avaliationSheetIndex];
            agfDTOArray[avaliationSheetIndex] = dto;

            String score = agf.getScore();
            if (score != null && score.Length > 0)
            {
                getAGFScoreLabel(avaliationSheetIndex).Text = score;
            }

            getAGFButton(avaliationSheetIndex).Enabled = true;
            Application.DoEvents();
        }

        /***********
         * Actions *
         ***********/
        private void saveButton_Click(object sender, EventArgs e)
        {
            saveFileDialog.ShowDialog();
            if (saveFileDialog.FileName != "")
            {
                //Write the actual file
//                FileStream fs = (FileStream)saveFileDialog.OpenFile();
//                StreamWriter sw = new StreamWriter(saveFileDialog.OpenFile());
//                sw.Write("TESTE");
//                sw.Close();
                PROFIPDTO profip = new PROFIPDTO();
                buildCapa(profip);
                buildAvaliacaoInicial(profip);
                buildAvaliacao1(profip);
                buildAvaliacao2(profip);
                buildAvaliacao3(profip);
                buildAvaliacao4(profip);
                profip.panssDTOArray = this.panssDTOArray;
                profip.bprsDTOArray = this.bprsDTOArray;
                profip.madrsDTOArray = this.madrsDTOArray;
                profip.pasDTOArray = this.pasDTOArray;
                profip.nosdupDTOArray = this.nosdupDTOArray;
                profip.asiDTOArray = this.asiDTOArray;
                profip.whoqolbrefDTOArray = this.whoqolbrefDTOArray;
                profip.agfDTOArray = this.agfDTOArray;

                //Build Writer
                Writer writer = new Writer();
                writer.profip = profip;

                //Write Form data to stream
                Stream stream = saveFileDialog.OpenFile();
                writer.Write(stream);
                stream.Close();
            }
        }

        private void openButton_Click(object sender, EventArgs e)
        {
            openFileDialog.ShowDialog();
            if (openFileDialog.FileName != "")
            {
                Loader loader = new Loader();
                Stream stream = openFileDialog.OpenFile();
                PROFIPDTO profip = loader.Load(stream);
                stream.Close();

                this.panssDTOArray = profip.panssDTOArray;
                this.bprsDTOArray = profip.bprsDTOArray;
                this.madrsDTOArray = profip.madrsDTOArray;
                this.pasDTOArray = profip.pasDTOArray;
                this.nosdupDTOArray = profip.nosdupDTOArray;
                this.asiDTOArray = profip.asiDTOArray;
                this.whoqolbrefDTOArray = profip.whoqolbrefDTOArray;
                this.agfDTOArray = profip.agfDTOArray;
                loadCapa(profip);
                loadAvaliacaoInicial(profip);
                loadAvaliacao1(profip);
                loadAvaliacao2(profip);
                loadAvaliacao3(profip);
                loadAvaliacao4(profip);
            }
        }

        private void loadScaleScore(int avaliationSheetIndex)
        {
            initializeScaleForm<PANSSForm, PANSSDTO>(panssArray, panssDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<BPRSForm, BPRSDTO>(bprsArray, bprsDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<MADRSForm, MADRSDTO>(madrsArray, madrsDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<PASForm, PASDTO>(pasArray, pasDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<NOSDUPForm, NOSDUPDTO>(nosdupArray, nosdupDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<ASIForm, ASIDTO>(asiArray, asiDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<WHOQOLBREFForm, WHOQOLBREFDTO>(whoqolbrefArray, whoqolbrefDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            initializeScaleForm<AGFForm, AGFDTO>(agfArray, agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
            updateAGF(agfDTOArray[avaliationSheetIndex], avaliationSheetIndex);
        }
        
        
        private void printButton_Click(object sender, EventArgs e)
        {
            printDialog.ShowDialog();
        }

        private void activateToxicos_CheckedChanged(object sender, EventArgs e)
        {
            List<Control> controls = new List<Control>();
            controls.Add(checkBox1);
            controls.Add(checkBox2);
            controls.Add(checkBox3);
            controls.Add(checkBox4);
            controls.Add(checkBox5);

            Utilities.propagateCheck((Control)sender, controls);
        }

        private void Aval1TC_CE_CheckedChanged(object sender, EventArgs e)
        {
            List<Control> controls = new List<Control>();
            controls.Add(checkBox13);
            controls.Add(checkBox14);
            controls.Add(checkBox15);

            Utilities.propagateCheck((Control)sender, controls);
        }

        private void Aval1TC_CEOutras_CheckedChanged(object sender, EventArgs e)
        {
            List<Control> controls = new List<Control>();
            controls.Add(richTextBox1);

            Utilities.propagateCheck((Control)sender, controls);
        }

        private void Aval1RMN_CE_CheckedChanged(object sender, EventArgs e)
        {
            List<Control> controls = new List<Control>();
            controls.Add(richTextBox2);

            Utilities.propagateCheck((Control)sender, controls);
        }

        private void Aval1EEG_CheckedChanged(object sender, EventArgs e)
        {
            List<Control> controls = new List<Control>();
            controls.Add(richTextBox3);

            Utilities.propagateCheck((Control)sender, controls);
        }

   }
}
